<?php
declare (strict_types = 1);

namespace app\model;

use app\common\model\CacheRefreshHandler;
use app\common\service\redis\PoolRedis;
use think\facade\Cache;
use think\Model;
use think\model\relation\HasMany;
use think\model\relation\HasOneThrough;

/**
 * @mixin \think\Model
 */
class AdminDormitory extends Model
{
    //
    const DORMITORY_COUNT_CACHE_KEY = 'dor_staff_group:';

    public function school() {
        return $this->belongsTo(AdminSchool::class, 'school_id')->bind([
            'school_name' => 'name'
        ]);
    }

    public function student(): hasMany {
        return $this->hasMany('AdminStudentDormitory', 'dormitory_id', 'id')
            ->where('is_delete', 0)
            ->field('id,dormitory_id,name student_dormitory_name');
    }

    public function unlock() {
        return $this->hasMany(AdminUnlockRecord::class, 'dormitory_id');
    }

    public static function onAfterWrite($model)
    {
        // 软删除后处理
        if ($model->getAttr('is_delete') == 1) {
            $redis = PoolRedis::instance();
            // 移除学校宿舍列表
            $redis->sRem(self::DORMITORY_COUNT_CACHE_KEY."school_".$model->getAttr('school_id'), $model->getAttr('id'));
            // 删除宿舍楼用户统计
            $redis->del(self::DORMITORY_COUNT_CACHE_KEY."user_count_".$model->getAttr('id'));
            AdminStudentDormitory::update(['is_delete' => 1], ['dormitory_id' => $model->getAttr('id'), 'is_delete' => 0]);
            // 删除查询缓存
            Cache::store('redis')->has('ApiInfo:searchAdminStudentDormitory_dor');
        }
    }
    public static function onAfterInsert($AdminDormitory)
    {
        CacheRefreshHandler::storeHandler('add', $AdminDormitory->toArray());
        // 删除查询缓存
        Cache::store('redis')->has('ApiInfo:searchAdminStudentDormitory_dor');
    }

    // 获取学校宿舍列表, key => dor_staff_group:list_{school_id} value => {dormitory_id}
    public static function getDorSimpleList($school_id = 0)
    {
        if (!self::notExistAndSetAllBySchool()) {
            return [];
        }
        $redis = PoolRedis::instance();
        $listKey = self::DORMITORY_COUNT_CACHE_KEY."school_";
        $keys = PoolRedis::scanAllForMatch($listKey."*");
        $list = [];
        if ($school_id > 0) {
            $list = $redis->sMembers($listKey.$school_id);
        } else {
            foreach ($keys as $key) {
                $list = array_merge($list, $redis->sMembers($key));
            }
        }
        return array_values($list);
    }

    // 宿舍楼用户统计数据
    public static function notExistAndSetAllByUser($refresh = false)
    {
        $redis = PoolRedis::instance();

        $countKey = AdminDormitory::DORMITORY_COUNT_CACHE_KEY."user_count_";
        $keys = PoolRedis::scanAllForMatch($countKey."*");
        if ($refresh) { // 刷新缓存
            foreach ($keys as $key) {
                $redis->del($key);
            }
        } elseif ($keys && count($keys) > 0) {
            return true;
        }

        $subsql = AdminStaff::where('is_delete', 0)
            ->where('type', AdminStaff::STUDENT)
            ->field("dormitory_id,count(id) value")
            ->group('dormitory_id')
            ->buildSql();
        $list = AdminDormitory::alias('ad')
            ->join(['admin_school' => 'school'], 'school.id=ad.school_id')
            ->leftJoin([$subsql => 's'], 's.dormitory_id=ad.id')
            ->where('school.is_delete', 0)
            ->where('ad.is_delete', 0)
            ->field('ad.id,ad.name,ifnull(s.value, 0) value')
            ->select()->toArray();

        $redis->multi();
        foreach ($list as $item) {
            $redis->hSet($countKey.$item['id'], 'name', $item['name']);
            $redis->hSet($countKey.$item['id'], 'value', $item['value']);
        }
        $redis->exec();
        return true;
    }

    // 学校宿舍楼统计数据
    public static function notExistAndSetAllBySchool($refresh = false)
    {
        $redis = PoolRedis::instance();

        $school_key = AdminDormitory::DORMITORY_COUNT_CACHE_KEY."school_";
        $keys = PoolRedis::scanAllForMatch($school_key."*");
        if ($refresh) {
            foreach ($keys as $key) {
                $redis->del($key);
            }
        } elseif ($keys && count($keys) > 0) {
            return true;
        }

        $list = AdminDormitory::hasWhere('school', function($query) {
                $query->where('is_delete', 0);
            })->alias('AdminDormitory')
            ->where('AdminDormitory.is_delete', 0)
            ->field('AdminDormitory.id,AdminDormitory.school_id')->select()->toArray();
        $redis->multi();
        foreach ($list as $item) {
            $redis->sAdd($school_key.$item['school_id'], $item['id']);
        }
        $redis->exec();
        return true;
    }
}
